package com.dd.cloud.user.service.chknowl.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.ChKnowlConstants;
import com.dd.cloud.common.constants.FileConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.ExtUtils;
import com.dd.cloud.common.utils.ObjectUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.chknowl.ChknowlBooksCategory;
import com.dd.cloud.user.entity.chknowl.ChknowlBooksCtlg;
import com.dd.cloud.user.entity.chknowl.ChknowlBooksPresent;
import com.dd.cloud.user.entity.file.FileInfo;
import com.dd.cloud.user.mapper.chknowl.ChknowlBooksPresentMapper;
import com.dd.cloud.user.req.chknowl.*;
import com.dd.cloud.user.res.chknowl.ChBooksCategoryRes;
import com.dd.cloud.user.res.chknowl.ChknowlBooksDetailRes;
import com.dd.cloud.user.res.chknowl.ChknowlBooksPresentPageRes;
import com.dd.cloud.user.service.chknowl.IChknowlBooksCategoryService;
import com.dd.cloud.user.service.chknowl.IChknowlBooksCtlgService;
import com.dd.cloud.user.service.chknowl.IChknowlBooksPresentService;
import com.dd.cloud.user.util.BookUtils;
import com.dd.cloud.user.util.HuaWeiOBSUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 古典书籍内容表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2022-07-04
 */
@Service
@Slf4j
public class ChknowlBooksPresentServiceImpl extends ServiceImpl<ChknowlBooksPresentMapper, ChknowlBooksPresent> implements IChknowlBooksPresentService {
    @Autowired
    private IChknowlBooksCtlgService chknowlBooksCtlgService;
    @Autowired
    private IChknowlBooksCategoryService chknowlBooksCategoryService;

    private static List<String> imgList = Arrays.asList("https://zk-ak.obs.cn-south-1.myhuaweicloud.com:443/dadao%2F%E4%B9%A6%E7%B1%8D%E5%B0%81%E9%9D%A2%E6%A8%A1%E7%89%88+2%403x.png",
            "https://zk-ak.obs.cn-south-1.myhuaweicloud.com:443/dadao%2F%E4%B9%A6%E7%B1%8D%E5%B0%81%E9%9D%A2%E6%A8%A1%E7%89%882%403x.png",
            "https://zk-ak.obs.cn-south-1.myhuaweicloud.com:443/dadao%2F%E4%B9%A6%E7%B1%8D%E5%B0%81%E9%9D%A2%E6%A8%A1%E7%89%883%403x.png");

    /**
     * 获取书籍大类
     *
     * @return
     */
    @Override
    public List<ChBooksCategoryRes> getCategory() {
        return getBaseMapper().getCategory();
    }

    /**
     * 分页获取大类中所有的书籍
     *
     * @param req
     * @return
     */
    @Override
    public IPage<ChknowlBooksPresentPageRes> getCategoryBookList(ChBooksPageReq req) {
        Page<ChknowlBooksPresentPageRes> page = req.pagePojo();
        page = getBaseMapper().getBooksPresentPage(page, req);
        return page;
    }

    /**
     * id查询书籍
     *
     * @param bookId
     * @return
     */
    @Override
    public ChknowlBooksPresentPageRes getCategoryBook(Integer bookId) {
        ChBooksPageReq req = new ChBooksPageReq();
//        req.setBookId(bookId);
//        req.setUserType(1);
        ChknowlBooksPresentPageRes res = getBaseMapper().getBooksPresentPage(req);
        return res;
    }

    /**
     * 通过id 和目录获取书籍内容
     *
     * @param id
     * @return
     */
    @Override
    public ChknowlBooksCtlg getContent(Integer id, Integer rankId) {
//        Integer rank = rankId;
//        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
//        if (rankId == null) {
//            QueryWrapper<ChknowlBooksRead> qw = new QueryWrapper<>();
//            qw.lambda().eq(ChknowlBooksRead::getBookId, id).
//                    eq(ChknowlBooksRead::getUserId, loginInfo.getId()).
//                    eq(ChknowlBooksRead::getUserType, loginInfo.getType());
//            ChknowlBooksRead read = chknowlBooksReadService.getOne(qw);
//            if (read == null) {
//                rank = 1;
//            } else {
//                rank = read.getRank() + 1;
//            }
//        }
//        ChknowlBooksCtlg ChknowlBooksCtlg = chknowlBooksCtlgService.getBooksCtlgContent(id, rank);
//
//        if (ChknowlBooksCtlg != null && ChknowlBooksCtlg.getContent() != null
//                && loginInfo.getType() == LoginInfo.UserType.DOCTOR) {
//            ChknowlBooksRead read = new ChknowlBooksRead();
//            read.setBookId(id);
//            read.setUserId(loginInfo.getId());
//            read.setUserType(loginInfo.getType());
//            read.setRank(rank);
//            UpdateWrapper<ChknowlBooksRead> uw = new UpdateWrapper<ChknowlBooksRead>();
//            uw.lambda().eq(ChknowlBooksRead::getBookId, id);
//            uw.lambda().eq(ChknowlBooksRead::getUserId, loginInfo.getId());
//            uw.lambda().eq(ChknowlBooksRead::getUserType, loginInfo.getType());
//            chknowlBooksReadService.saveOrUpdate(read, uw);
//        }
//        return ChknowlBooksCtlg;
        return new ChknowlBooksCtlg();
    }

    /**
     * 禁用或删除书籍
     *
     * @param bookId
     * @param status
     */
    @Override
    public void updateBookContentStatus(Integer bookId, Integer status) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        ChknowlBooksPresent present = getById(bookId);
        if (present == null) {
            throw new ZekeException(400, "书籍不存在");
        }
        if (present.getStatus().equals(status)) {
            return;
        }
        if (!ObjectUtils.refrect(ChKnowlConstants.ContentStatus.class, status)) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        present.setStatus(status);
        present.setOperDate(LocalDateTime.now());
        present.setOperId(loginInfo.getId());
        boolean i = updateById(present);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.UPDATE_ERROR);
        }
    }

    /**
     * 添加书籍
     *
     * @param req
     */
    @Override
    @Transactional
    public void addBook(ChknowlBooksCreateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();

        if (!ObjectUtils.refrect(ChKnowlConstants.ContentStatus.class, req.getStatus())) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        QueryWrapper<ChknowlBooksPresent> qq = new QueryWrapper<>();
        qq.lambda().select(ChknowlBooksPresent::getId)
                .eq(ChknowlBooksPresent::getName, req.getName())
                .ne(ChknowlBooksPresent::getStatus, ChKnowlConstants.ContentStatus.DELETE);
        ChknowlBooksPresent present = getOne(qq);
        if (present == null) {
            //不存在书籍, 添加书籍和目录
            present = new ChknowlBooksPresent();
            BeanUtils.copyProperties(req, present);
            present.setOperId(loginInfo.getId());
            present.setCreateDate(LocalDateTime.now());
            present.setOperDate(LocalDateTime.now());
            Integer flag = getBaseMapper().insert(present);
            if (flag <= 0) {
                throw new ZekeException(400, "书籍添加失败");
            }
        }
        ChknowlBooksCtlgReq ctlgReq = new ChknowlBooksCtlgReq();
        BeanUtils.copyProperties(req, ctlgReq);
        ctlgReq.setBookId(present.getId());
        chknowlBooksCtlgService.addBooksCtlg(ctlgReq);
    }

    /**
     * 修改书籍
     *
     * @param req
     */
    @Override
    @Transactional
    public void updateBook(ChknowlBooksUpdateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        if (!ObjectUtils.refrect(ChKnowlConstants.ContentStatus.class, req.getStatus())) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        ChknowlBooksPresent present = getById(req.getBookId());
        if (present == null) {
            throw new ZekeException(400, "书籍不存在");
        }
        present.setName(req.getName());
        present.setCover(req.getCover());
//        present.setCategory(req.getCategory());
        present.setStatus(req.getStatus());
        present.setOperId(loginInfo.getId());
        present.setOperDate(LocalDateTime.now());
        Integer flag = getBaseMapper().updateById(present);
        if (flag <= 0) {
            throw new ZekeException(400, "书籍修改失败");
        }
        chknowlBooksCtlgService.updateBooksCtlg(req);
    }

    /**
     * 查询书籍详细信息
     *
     * @param bookId
     * @return
     */
    @Override
    public ChknowlBooksDetailRes getBookDetail(Integer bookId) {
        ChknowlBooksPresent present = getById(bookId);
        if (present == null) {
            throw new ZekeException(400, "书籍不存在");
        }
        ChknowlBooksDetailRes res = new ChknowlBooksDetailRes();
        BeanUtils.copyProperties(present, res);
        return res;
    }

    @Override
    public List<FileInfo> uploadMultipleFile(MultipartFile[] files) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        List<FileInfo> list = new ArrayList<>();
        for (int j = 0; j < files.length; j++) {
            MultipartFile file = files[j];
            FileInfo fileInfo = new FileInfo();
            fileInfo.setFileName(file.getName());
            fileInfo.setFileOriginalName(file.getOriginalFilename());
            //文件大小, 字节数 转成KB需/1024
            fileInfo.setFileSize(file.getSize());
            String url = HuaWeiOBSUtil.uploadFile(file);
            fileInfo.setFileUrl(url);
            if (loginInfo != null) {
                fileInfo.setFounderId(loginInfo.getId());
                fileInfo.setFounderType(loginInfo.getType());
                fileInfo.setFounderName(loginInfo.getName());
            }
            fileInfo.setCreateDate(LocalDateTime.now());
            fileInfo.setContentType(file.getContentType());
            fileInfo.setStatus(FileConstants.FileStatus.NOMAL);
            list.add(fileInfo);
            LambdaQueryWrapper<ChknowlBooksPresent> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ChknowlBooksPresent::getName, file.getOriginalFilename());
            ChknowlBooksPresent chknowlBooksPresent = this.getOne(wrapper);
            chknowlBooksPresent.setBookUrl(url);
            Integer bookId = chknowlBooksPresent.getId();
        }
//        boolean i = saveBatch(list);
//        if (!i) {
//            throw new ZekeException(500, "文件保存失败");
//        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBookBatch(MultipartFile[] files) {
//        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        List<FileInfo> list = new ArrayList<>();
        List<ChknowlBooksPresent> booksList = new ArrayList<>();
        for (int j = 0; j < files.length; j++) {
            MultipartFile file = files[j];
            String originalFilename = file.getOriginalFilename();
            String[] strs = originalFilename.split("\\.");
            log.info("书籍名字:{}", strs[0]);
            LambdaQueryWrapper<ChknowlBooksPresent> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ChknowlBooksPresent::getName, strs[0])
                    .eq(ChknowlBooksPresent::getStatus, 1);
            List<ChknowlBooksPresent> chknowlBooksPresents = this.list(wrapper);
            if (chknowlBooksPresents.size() != 1) {
                log.info("~查询书籍失败~" + strs[0]);
                continue;
            }
            ChknowlBooksPresent chknowlBooksPresent = chknowlBooksPresents.get(0);
            String bookUrl = HuaWeiOBSUtil.uploadFile(file);
            chknowlBooksPresent.setBookUrl(bookUrl);
            booksList.add(chknowlBooksPresent);
        }
//        if (CollectionUtil.isNotEmpty(list)) {
//            boolean i = fileInfoService.saveBatch(list);
//            if (!i) {
//                throw new ZekeException(500, "文件保存失败");
//            }
//        }
        if (CollectionUtil.isNotEmpty(booksList)) {
            boolean flag = this.saveOrUpdateBatch(booksList);
            if (!flag) {
                throw new ZekeException("更新书籍失败");
            }
//            for (ChknowlBooksPresent item : booksList) {
//                //延时5s
//                DelayMqVo<Integer> delayMqVo = new DelayMqVo<>();
//                delayMqVo.setT(item.getId());
//                delayMqVo.setType(DelayMqVo.DelayMqVoType.BOOK_TRANSITION);
//                long ms2 = 1000 * 5;
//                rabbitSend.sendMessageDelay(MQConfig.DELAY_EXCHANGE, MQConfig.DELAY_KEY, delayMqVo, ms2);
//            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void getBookTransition(Integer bookId) {
        ChknowlBooksPresent booksPresent = this.getById(bookId);
        if (booksPresent == null) {
            log.info("书籍不存在");
            return;
        }
        String bookUrl = booksPresent.getBookUrl();
        if (StringUtils.isBlank(bookUrl)) {
            log.info("书籍路径不存在");
            return;
        }
        //获取书籍目录
        BookUtils.getBookPresentRank(bookUrl, bookId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importBookBatch(MultipartFile file) {
        List<ExcelAddBookModel> list;
        try {
            if (file == null) {
                throw new ZekeException("请上传文件");
            }
            list = ExtUtils.importExcel(file, 0, 1, ExcelAddBookModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException("解析Excel失败");
        }
        if (list == null || list.isEmpty()) {
            throw new ZekeException("数据为空");
        }
        int index = 0;
        List<ChknowlBooksPresent> chknowlBooksPresents = new ArrayList<>();
        for (ExcelAddBookModel bookModel : list) {
            Integer categoryId = null;
            String categoryName = bookModel.getCategoryName();
            LambdaQueryWrapper<ChknowlBooksCategory> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ChknowlBooksCategory::getName, categoryName)
                    .eq(ChknowlBooksCategory::getStatus, 1);
            ChknowlBooksCategory chknowlBooksCategory = chknowlBooksCategoryService.getOne(wrapper);
            if (chknowlBooksCategory == null) {
                Integer sort = 1;
                LambdaQueryWrapper<ChknowlBooksCategory> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.orderByDesc(ChknowlBooksCategory::getSort)
                        .eq(ChknowlBooksCategory::getStatus, 1)
                        .last("limit 1");
                ChknowlBooksCategory chknowlBooksCategory1 = chknowlBooksCategoryService.getOne(wrapper1);
                if (chknowlBooksCategory1 != null) {
                    sort = chknowlBooksCategory1.getSort() + 1;
                }
                ChknowlBooksCategory newCategory = new ChknowlBooksCategory();
                newCategory
                        .setName(categoryName)
                        .setStatus(1)
                        .setSort(sort)
                        .setCreateDate(LocalDateTime.now());
                chknowlBooksCategoryService.save(newCategory);
                categoryId = newCategory.getId();
            } else {
                categoryId = chknowlBooksCategory.getId();
            }
            //保存业务
            ChknowlBooksPresent booksPresent = new ChknowlBooksPresent();
            booksPresent.setName(bookModel.getName())
                    .setCreateDate(LocalDateTime.now())
                    .setAuthor(bookModel.getAuthor())
                    .setIntroduction(bookModel.getIntroduction())
                    .setCategoryId(categoryId)
                    .setStatus(1)
                    .setCover(imgList.get(index % 3));
            index++;
            chknowlBooksPresents.add(booksPresent);
        }
        if (CollectionUtil.isNotEmpty(chknowlBooksPresents)) {
            this.saveBatch(chknowlBooksPresents);
        }
    }

    @Override
    public void importBookImgBatch() {
        LambdaQueryWrapper<ChknowlBooksPresent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChknowlBooksPresent::getStatus, 1);
        List<ChknowlBooksPresent> chknowlBooksPresentList = this.list(wrapper);
        if (CollectionUtil.isNotEmpty(chknowlBooksPresentList)) {
            for (int i = 0; i < chknowlBooksPresentList.size(); i++) {
                chknowlBooksPresentList.get(i).setCover(imgList.get(i % 3));
            }
            Boolean flag = this.updateBatchById(chknowlBooksPresentList);
            if (!flag) {
                throw new ZekeException("~更新图片失败~");
            }
        }
    }

    @Override
    public void importBookBatchTwo(MultipartFile file) {
        List<ExcelAddBookModel> list;
        try {
            if (file == null) {
                throw new ZekeException("请上传文件");
            }
            list = ExtUtils.importExcel(file, 0, 1, ExcelAddBookModel.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ZekeException("解析Excel失败");
        }
        if (list == null || list.isEmpty()) {
            throw new ZekeException("数据为空");
        }
        List<ChknowlBooksPresent> chknowlBooksPresents = new ArrayList<>();
        for (ExcelAddBookModel bookModel : list) {
            Integer categoryId = null;
            String categoryName = bookModel.getCategoryName();
            LambdaQueryWrapper<ChknowlBooksCategory> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ChknowlBooksCategory::getName, categoryName)
                    .eq(ChknowlBooksCategory::getStatus, 1);
            ChknowlBooksCategory chknowlBooksCategory = chknowlBooksCategoryService.getOne(wrapper);
            if (chknowlBooksCategory == null) {
                Integer sort = 1;
                LambdaQueryWrapper<ChknowlBooksCategory> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.orderByDesc(ChknowlBooksCategory::getSort)
                        .eq(ChknowlBooksCategory::getStatus, 1)
                        .last("limit 1");
                ChknowlBooksCategory chknowlBooksCategory1 = chknowlBooksCategoryService.getOne(wrapper1);
                if (chknowlBooksCategory1 != null) {
                    sort = chknowlBooksCategory1.getSort() + 1;
                }
                ChknowlBooksCategory newCategory = new ChknowlBooksCategory();
                newCategory
                        .setName(categoryName)
                        .setStatus(1)
                        .setSort(sort)
                        .setCreateDate(LocalDateTime.now());
                chknowlBooksCategoryService.save(newCategory);
                categoryId = newCategory.getId();
            } else {
                categoryId = chknowlBooksCategory.getId();
            }
            //保存业务
            ChknowlBooksPresent booksPresent = new ChknowlBooksPresent();
            booksPresent.setName(bookModel.getName())
                    .setCreateDate(LocalDateTime.now())
                    .setAuthor(bookModel.getAuthor())
                    .setIntroduction(bookModel.getIntroduction())
                    .setCategoryId(categoryId);
            chknowlBooksPresents.add(booksPresent);
        }
        if (CollectionUtil.isNotEmpty(chknowlBooksPresents)) {
            this.saveBatch(chknowlBooksPresents);
        }
    }


}

